# Author : Chimengmeng
# Time : 2023/12/11
# Blog : https://www.cnblogs.com/dream-ze
# Wechat ： OXiMengYaO(备注来源)
import time

login_user_dict = {'username': '',
                   'role': '',
                   "bank_id": '',
                   "bank_pay_pwd": "",
                   "balance": ""
                   }


def create_data_type(tag, *args, **kwargs):
    # print(kwargs)  # {'username': 'dream', 'password': '521', 'role': 'admin'}
    if tag == 'pwd':
        data = '|'.join(kwargs.values())  # dream|521|admin
        return data
    elif tag == 'bank':
        data = '|'.join([str(value) for value in kwargs.values()])
        return data


def read_data(path, tag=None):
    user_pwd_dict = {}
    user_bank_dict = {}
    with open(path, 'r', encoding='utf8') as fp:
        data = fp.read()
    data_list = data.split('\n')
    data_list.pop()
    if tag == 'pwd':
        for data in data_list:
            username, password, role = data.split('|')
            user_pwd_dict[username] = {'password': password, 'role': role}
        # {'dream': {'password': '521', 'role': 'admin'}}
        return user_pwd_dict
    elif tag == 'bank':
        for data in data_list:
            username, pay_pwd, bank_id, balance = data.split('|')
            user_bank_dict[username] = {'pay_pwd': pay_pwd, 'bank_id': bank_id, 'balance': balance}
        return user_bank_dict


def save_data(path, data, mode='a'):
    with open(path, mode, encoding='utf8') as fp:
        fp.write(data + '\n')


def get_user_pwd():
    # 【1】要获取用户名和密码
    username = input("用户名 :>>>> ").strip()
    password = input("密码 :>>>> ").strip()
    return username, password


def register():
    username, password = get_user_pwd()
    # 【2】拼接存储数据的格式
    if username == 'dream' and password == '521':
        role = 'admin'
    else:
        role = 'normal'
    pwd_data = create_data_type(tag='pwd', username=username, password=password, role=role)
    bank_data = create_data_type(tag='pwd', username=username, bank_password='None', bank_id='0', balance='0')
    # print(pwd_data) # dream|521|admin
    # 【3】存储数据
    # [3.1]用户名和密码
    save_data(path='user_pwd.txt', data=pwd_data)
    save_data(path='user_log.txt', data=f'当前用户 {username} 注册成功 | {time.strftime("%x %X")}')
    # [3.2]银行信息
    save_data(path='user_bank.txt', data=bank_data)
    save_data(path='user_log.txt', data=f'当前用户 {username} 初始化银行卡成功 | {time.strftime("%x %X")}')
    # print(bank_data)# dream|None|0|0
    return True, f'{username} 注册成功!'


def init_bank_data(username):
    user_bank_dict = read_data(tag='bank', path='user_bank.txt')
    user_bank_data = user_bank_dict.get(username)
    login_user_dict['bank_id'] = user_bank_data.get('bank_id')
    login_user_dict['bank_pay_pwd'] = user_bank_data.get('pay_pwd')
    login_user_dict['balance'] = user_bank_data.get('balance')


def login():
    username, password = get_user_pwd()
    user_pwd_dict = read_data(tag='pwd', path='user_pwd.txt')
    user_data = user_pwd_dict.get(username)
    if not user_data:
        return False, '没有注册'
    if password != user_data.get('password'):
        return False, '密码失败!'
    login_user_dict['username'] = username
    login_user_dict['role'] = user_data.get('role')
    init_bank_data(username)
    return True, f'用户 {username} 登陆成功'


def login_auth(func):
    def inner(*args, **kwargs):
        # print(func.__name__) # add_bank_info

        # 【1】执行原函数的前提是已经登录过
        if not login_user_dict['username']:
            return False, f'必须先登录'
        if not login_user_dict['bank_id'] and func.__name__ != 'add_bank_info':
            return False, '必须先激活银行卡'
        return func(*args, **kwargs)

    return inner


@login_auth
def add_bank_info():
    username = login_user_dict['username']
    bank_pay_pwd = input("请输入支付密码 :>>>> ").strip()
    bank_id = input("请输入银行卡号 :>>>> ").strip()
    bank_data = create_data_type(tag='bank', username=username, bank_pay_pwd=bank_pay_pwd, bank_id=bank_id,
                                 balance=1000)
    save_data(path='user_bank.txt', data=bank_data)
    init_bank_data(username)
    print(login_user_dict)
    return True, f'初始化银行信息完成!'


def outer(func):
    def inner(*args, **kwargs):
        data = read_data('user_bank.txt', tag='bank')
        print(data)
        balance, bank_id, bank_pwd = func()
        login_data = data.get(login_user_dict['username'])
        print(login_data)
        old_balance = int(login_data['balance'])
        if not balance.isdigit():
            return False, f"金额输入格式有误"
        balance = int(balance)
        if not 0 < balance <= old_balance:
            return False, f"金额输入有误"
        if not bank_id.isdigit():
            return False, f'银行卡号必须是数字'
        elif len(bank_id) != 6:
            return False, f'银行卡号必须是六位'
        elif bank_id != login_data['bank_id']:
            return False, f"银行卡号与登录用户账号下的卡号不对，请检查卡号或重新登录！"
        if len(bank_pwd) != 3:
            return False, f'支付密码必须是3位'
        elif bank_pwd != login_data['pay_pwd']:
            return False, f"支付密码输入错误"
        data = create_data_type(tag='bank', username=login_user_dict['username'], bank_password=bank_pwd,
                                bank_id=bank_id, balance=old_balance - balance)
        save_data('user_bank.txt', data)
        save_data('user_log.txt',
                  f"当前用户{login_user_dict['username']}取款成功{balance} |{time.strftime('%x %X')}")
        return True, f"取款{balance}成功！"

    return inner


# 在装饰器内部完成 --- 格式校验。位数校验。数字余额校验
@outer
def get_balance(*args, **kwargs):
    # 【输入银行卡号】 +++ 符合六位数
    # 【输入支付密码】 +++ 符合指定的位数
    balance = input("请输入金额（不小于零) :>>>> ").strip()  # 余额是数字类型并且余额大于0小于你的余额
    bank_id = input("请输入银行卡号(6位数字) :>>>> ").strip()  # 确认是数字并且是六位
    bank_pwd = input("请输入支付密码(3位密码) :>>>> ").strip()  # 确认是数字并且是三位
    return balance, bank_id, bank_pwd
    # 确保我的银行卡号是 数字
    # if not bank_id.isdigit():
    #     return False, f'必须是数字'
    # if len(bank_id) != 6:
    #     return False, f'必须是六位'
    # if len(bank_pwd) != 3:
    #     return False, f'支付密码必须是3位'


# print(get_balance())
def check_flow():
    ...


def check_bank_info():
    ...


func_menu = '''
===================用户功能菜单=====================
                  1.注册
                  2.登陆
                  6.初始化银行信息
                  3.取款
                  4.查看流水
                  5.查看银行信息(查看自己的卡号、余额、流水等信息)
======================欢迎使用=======================
'''

func_dict = {
    '1': register,
    '2': login,
    '3': get_balance,
    '4': check_flow,
    '5': check_bank_info,
    '6': add_bank_info
}


def main():
    while True:
        print(func_menu)
        func_id = input("功能ID  :>>>> ").strip()
        if func_id not in func_dict.keys():
            print(f"不存在")
            continue
        func = func_dict[func_id]
        flag, msg = func()
        if flag:
            print(msg)
        else:
            print(msg)
            continue


main()
